package filter;

public class Gaussian implements FilterModule{
	
	Raster dst = null;
	private double filter[][] = { { 1/16.0, 1/8.0, 1/16.0 }, { 1/8.0, 1/4.0, 1/8.0 }, { 1/16.0, 1/8.0, 1/16.0 } };
		
	public boolean exec( Raster image, int cp, int allowance ){
		if( dst == null )
			dst = new Raster( image.width, image.height );
		
		int n_did = 0;
		
		int i = cp / image.height + 1;
		int j = cp % image.height + 1;
		
		
		for( ; i < image.height + 1; i++ ){
			for( ; j < image.width + 1; j++ ){
				int src_r[][] = { { image.r[ i - 1 ][ j - 1 ], image.r[ i - 1 ][ j ], image.r[ i - 1 ][ j + 1 ] },
								{ image.r[ i ][ j - 1 ], image.r[ i ][ j ], image.r[ i ][ j + 1 ] },
								{ image.r[ i + 1 ][ j - 1 ], image.r[ i + 1 ][ j ], image.r[ i + 1 ][ j + 1 ] } };
				dst.r[ i ][ j ] = ( short )convolve( src_r );

				int src_g[][] = { { image.g[ i - 1 ][ j - 1 ], image.g[ i - 1 ][ j ], image.g[ i - 1 ][ j + 1 ] },
								{ image.g[ i ][ j - 1 ], image.g[ i ][ j ], image.g[ i ][ j + 1 ] },
								{ image.g[ i + 1 ][ j - 1 ], image.g[ i + 1 ][ j ], image.g[ i + 1 ][ j + 1 ] } };
				dst.g[ i ][ j ] = ( short )convolve( src_g );

				int src_b[][] = { { image.b[ i - 1 ][ j - 1 ], image.b[ i - 1 ][ j ], image.b[ i - 1 ][ j + 1 ] },
								{ image.b[ i ][ j - 1 ], image.b[ i ][ j ], image.b[ i ][ j + 1 ] },
								{ image.b[ i + 1 ][ j - 1 ], image.b[ i + 1 ][ j ], image.b[ i + 1 ][ j + 1 ] } };
				dst.b[ i ][ j ] = ( short )convolve( src_b );
				
				if( ++cp >= image.height * image.width ){
					for( int n = 1; n < image.height + 1; n++ ){
						for( int m = 1; m < image.width + 1; m++ ){
							image.r[ n ][ m ] = dst.r[ n ][ m ];
							image.g[ n ][ m ] = dst.g[ n ][ m ];
							image.b[ n ][ m ] = dst.b[ n ][ m ];
						}
					}
					return true;
				}
				
				if( ++n_did >= allowance )
					return false;
			}
			j = 1;
		}
		
		return true;
	}//end-of-exec()
	
	private int convolve( int[][] src ){
		int res = ( int )( src[ 0 ][ 0 ] * filter[ 0 ][ 0 ] + src[ 0 ][ 1 ] * filter[ 0 ][ 1 ] + src[ 0 ][ 2 ] * filter[ 0 ][ 2 ]
				+ src[ 1 ][ 0 ] * filter[ 1 ][ 0 ] + src[ 1 ][ 1 ] * filter[ 1 ][ 1 ] + src[ 1 ][ 2 ] * filter[ 1 ][ 2 ]
				+ src[ 2 ][ 0 ] * filter[ 2 ][ 0 ] + src[ 2 ][ 1 ] * filter[ 2 ][ 1 ] + src[ 2 ][ 2 ] * filter[ 2 ][ 2 ] );
		
		return res;
	}
	
	public String get_name(){
		return "Gaussian_blur";
	}
}//end-of-class
